package com.bottle.android_mvvm.ui.view

import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import androidx.viewbinding.ViewBinding
import com.bottle.android_mvvm.domain.ext.getVmClazz
import com.bottle.android_mvvm.domain.viewmodel.BaseMVVMViewModel
import com.bottle.lib_core.ui.view.BaseBingActivity

/**
 * BaseMVVMActivity 是一个抽象基类，基于 MVVM 架构设计，结合 ViewBinding 提供了更简洁的视图绑定方式。
 * 它继承自 [BaseBingMVVMActivity]，并扩展了 ViewModel 的功能，适用于所有需要使用 MVVM 架构的 Activity 场景。
 *
 * ### 主要功能
 * 1. **ViewBinding 支持**：通过 [inflateBindingWithGeneric] 方法动态创建 ViewBinding 实例，避免手动 findViewById 操作。
 * 2. **ViewModel 支持**：通过 [ViewModelProvider] 创建并管理 ViewModel 实例。
 * 3. **LiveData 观察者**：提供 [createObserver] 方法，允许子类创建 LiveData 数据观察者。
 * 4. **UI 事件注册**：通过 [registerUiChange] 方法注册 UI 事件，如显示和隐藏加载等待框。
 * 5. **布局加载**：重写了 [layoutId] 和 [initDataBind] 方法，使用 ViewBinding 替代传统的布局资源 ID 加载方式。
 * 6. **简化视图操作**：通过 [bing] 属性提供对 ViewBinding 的直接访问，方便在子类中操作视图组件。
 *
 * ### 关键属性
 * - [_viewModel]: 私有属性，存储当前 Activity 的 ViewModel 实例。
 * - [vm]: 公开只读属性，用于在子类中访问 ViewModel 实例。
 * - [_binding]: 私有属性，存储当前 Activity 的 ViewBinding 实例。
 * - [bing]: 公开只读属性，用于在子类中访问 ViewBinding 实例。
 *
 * ### 生命周期方法
 * - [onCreate]: 初始化 ViewModel 实例，注册 UI 事件，并调用 [createObserver] 方法创建 LiveData 数据观察者。
 * - [layoutId]: 返回值固定为 0，表示不使用传统的布局资源 ID 加载方式。
 * - [initDataBind]: 创建并初始化 ViewBinding 实例，并返回其根视图以设置内容视图。
 *
 * ### 抽象方法
 * - [createObserver]: 子类必须实现此方法，用于创建 LiveData 数据观察者。
 *
 * ### 使用场景
 * - 适用于所有需要继承 Activity 并使用 MVVM 架构的模块化开发场景。
 * - 提供了统一的 ViewModel 和 ViewBinding 初始化逻辑，减少重复代码。
 *
 */
abstract class BaseMVVMActivity<VM : BaseMVVMViewModel, VB : ViewBinding> : BaseBingActivity<VB>(){
    //延迟初始化的viewModel变量
    private lateinit var _viewModel: VM
    //提供viewModel的getter方法
    val vm: VM get() = _viewModel

    /**
     * Activity的生命周期方法，用于初始化viewModel、注册UI事件和创建数据观察者
     */
    override fun onCreate(savedInstanceState: Bundle?) {
        //初始化viewModel
        _viewModel = createViewModel()
        //调用父类的onCreate方法
        super.onCreate(savedInstanceState)
        //注册UI事件
        registerUiChange()
        //创建数据观察者
        createObserver()
    }

    /**
     * 创建viewModel
     */
    private fun createViewModel(): VM {
        //通过ViewModelProvider获取viewModel实例
        return ViewModelProvider(this)[getVmClazz(this)]
    }

    /**
     * 创建liveData数据观察者
     */
    abstract fun createObserver()

    /**
     * 注册UI 事件
     */
    private fun registerUiChange() {
        //显示弹窗
        _viewModel.loadingChange.showDialog.observeForever {
            showLoading(
                it.message,
                it.cancelable,
                it.hasShadowBg,
                it.cancelTime,
                it.waitTime,
                it.useView,
                it.onCancelListener,
                it.onDismissListener
            )
        }
        //关闭弹窗
        _viewModel.loadingChange.dismissDialog.observe(this) {
            dismissLoading()
        }
    }
}